import { Link, Contribution } from '@brillout/docpress'
import { UiFrameworkExtension, ProvidedBy, Figure, ConfigSpec } from '../../components'
import { LoadingComponent } from './LoadingComponent'

<ConfigSpec
  env={<>client, and server if <Link href="/ssr"><code>ssr: true</code></Link></>}
  cumulative={false}
  providedBy={<ProvidedBy list={['vike-react']} noCustomGuide={true}>the <code>+Loading</code> setting</ProvidedBy>}
/>

<Contribution>
  Contributions welcome to implement the `+Loading` setting for `vike-vue` and `vike-solid`.
</Contribution>

The `+Loading` setting adds `<Suspense>` fallbacks, with the purpose of showing loading animations.

```tsx
// pages/+Loading.tsx

export default {
  layout: LoadingLayout,
  component: LoadingComponent
}

function LoadingLayout() {
  // Shown when a page or layout is loading
  return <div>Loading...</div>
}

function LoadingComponent() {
  // Shown when a component is loading
  return <div>Loading...</div>
}
```

This is how `+Loading` is embedded:

```jsx
<Suspense fallback={Loading.layout}>             ⟸ component defined by +Loading.layout
  <Layout>                                       ⟸ component defined by +Layout
    <Page>                                       ⟸ component defined by +Page
      {/* ... */}
      <Suspense fallback={Loading.component}>    ⟸ component defined by +Loading.component
        <SomeComponent />
      </Suspense>
      {/* ... */}
    </Page>
  </Layout>
</Suspense>
```

> This means that `+Loading` is only used if components suspend. Consequently:
> - If your app doesn't include any suspending components, then `+Loading` has no effect.
> - If you use <Link href="/data">`+data`</Link>, then `+Loading` has no effect — because `+data` pauses the entire rendering process (it doesn't suspend any component).
>
> The `+Loading` component is commonly used by [`vike-react-query`](https://github.com/vikejs/vike-react/tree/main/packages/vike-react-query#readme) and [`vike-react-apollo`](https://github.com/vikejs/vike-react/tree/main/packages/vike-react-apollo#readme) users, as these extensions suspend components.

## Default

The default `Loading.component` is:

<Figure width={400} text={<>This is the default loading animation. Its width is <code>100%</code> of the parent (here the parent's width is artificially set to <code>400px</code>). Its height is <code>width * 0.4</code>.</>}>
  <LoadingComponent />
</Figure>

If you want to show a different loading animation, then define `Loading.component` in order to override the default.


## See also

- [vike-react-query](https://github.com/vikejs/vike-react/tree/main/packages/vike-react-query#readme)
- [vike-react-apollo](https://github.com/vikejs/vike-react/tree/main/packages/vike-react-apollo#readme)
